package hu.uszeged.inf.wlab.stunner.screens.bookmarks;

import hu.uszeged.inf.wlab.stunner.R;
import hu.uszeged.inf.wlab.stunner.database.STUNnerContract;
import hu.uszeged.inf.wlab.stunner.database.dtos.DiscoveryDTO;
import hu.uszeged.inf.wlab.stunner.screens.bookmarks.adapter.BookmarkAdapter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.ContentUris;
import android.content.DialogInterface;
import android.database.Cursor;
import android.location.Address;
import android.location.Geocoder;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.ListView;

/**
 * {@link ActionBarActivity} implementation to show the bookmarked discoveries.
 * 
 * @author szelezsant
 */
public class BookmarksActivity extends ActionBarActivity implements LoaderCallbacks<Cursor> {

	/** The list of discoveryDTOs to show. */
	private final List<DiscoveryDTO> discoveryDTOs = new ArrayList<DiscoveryDTO>();

	@Override
	protected void onCreate(final Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		/* initialize the UI */
		supportRequestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
		setContentView(R.layout.activity_bookmarks);
		getSupportActionBar().setHomeButtonEnabled(true);
		getSupportLoaderManager().restartLoader(0, null, this);
		final ListView listView = (ListView) findViewById(R.id.listViewBookmarks);
		listView.setOnItemLongClickListener(new OnItemLongClickListener() {

			@Override
			public boolean onItemLongClick(final AdapterView<?> parent, final View row, final int position, final long identifier) {
				Log.i(getClass().getSimpleName(), "onItemLongClick: position=" + position + ", id=" + identifier);

				final DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {

					@Override
					public void onClick(final DialogInterface dialog, final int which) {
						if (DialogInterface.BUTTON_POSITIVE == which) {
							final int deletedRowsCount = getContentResolver().delete(
									ContentUris.withAppendedId(STUNnerContract.Discovery.CONTENT_URI, identifier), null,
									null);
							/* if the delete was successful, remove the entry from the adapter and from the fragment arguments */
							if (1 == deletedRowsCount) {
								discoveryDTOs.remove(position);
								((BaseAdapter) parent.getAdapter()).notifyDataSetChanged();
							}
						}
						dialog.dismiss();
					}
				};
				new AlertDialog.Builder(BookmarksActivity.this).setTitle(R.string.warning).setMessage(R.string.delete_prompt)
						.setNegativeButton(android.R.string.no, listener).setPositiveButton(android.R.string.yes, listener).create().show();

				return true;
			}
		});

		listView.setEmptyView(findViewById(R.id.textViewEmptyLabel));
	}

	@Override
	public Loader<Cursor> onCreateLoader(final int loaderId, final Bundle params) {
		Log.i(getClass().getSimpleName(), "onCreateLoader");
		setSupportProgressBarIndeterminateVisibility(true);
		return new CursorLoader(this, STUNnerContract.Discovery.CONTENT_URI, null, STUNnerContract.Discovery.COLUMN_BOOKMARKED + "=?",
				new String[] {"1"}, STUNnerContract.Discovery.COLUMN_TIMESTAMP + " desc");
	}

	@TargetApi(Build.VERSION_CODES.HONEYCOMB)
	@Override
	public void onLoadFinished(final Loader<Cursor> cursorLoader, final Cursor completeCursor) {
		Log.i(getClass().getSimpleName(), "onLoadFinished");
		if (completeCursor != null && completeCursor.moveToFirst()) {
			while (completeCursor.moveToNext()) {
				discoveryDTOs.add(STUNnerContract.Discovery.cursorToDTO(completeCursor));
			}
			completeCursor.close();

			if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
				new LocationDecoderTask().execute();
			} else {
				new LocationDecoderTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
			}
		} else {
			setSupportProgressBarIndeterminateVisibility(false);
		}
	}

	@Override
	public void onLoaderReset(final Loader<Cursor> cursorLoader) {
		Log.i(getClass().getSimpleName(), "onLoaderReset");
	}

	/**
	 * Decodes the location from the coordinates on a worker thread.
	 * 
	 * @author szelezsant
	 */
	private class LocationDecoderTask extends AsyncTask<Void, Void, Void> {

		@Override
		protected Void doInBackground(final Void... params) {
			final Geocoder geocoder = new Geocoder(BookmarksActivity.this, Locale.getDefault());
			try {
				for (final DiscoveryDTO dto : discoveryDTOs) {
					final List<Address> addresses = geocoder.getFromLocation(dto.getLatitude(), dto.getLongitude(), 1);
					if (addresses != null && !addresses.isEmpty()) {
						final Address address = addresses.get(0);
						dto.setLocation(address.getCountryName().concat(", ").concat(address.getLocality()).concat(", ")
								.concat(address.getThoroughfare()));
					}
				}
			} catch (final IOException ioException) {
				Log.e(getClass().getSimpleName(), "failed to decode location: " + ioException);
			}

			return null;
		}

		@Override
		protected void onPostExecute(final Void result) {
			((ListView) findViewById(R.id.listViewBookmarks)).setAdapter(new BookmarkAdapter(discoveryDTOs));
			setSupportProgressBarIndeterminateVisibility(false);

			super.onPostExecute(result);
		}

	}
}
